using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using Microsoft.SPOT;
using Socket = System.Net.Sockets.Socket;

namespace CobraController
{

  public class SocketClient
  {
    private static string _message { get; set; }

    public static void Send(string message)
    {
      _message = message;
      Thread st = new Thread(new ThreadStart(sendmsg));
      st.Start();
    }

    private static void sendmsg()
    {
      try
      {
        GetWebPage(Settings.DomoticaServerIP, Settings.DomoticaServerPort);
        //Debug.Print(html);
      }
      catch (SocketException se)
      {
        if (se.ErrorCode == (int)SocketErrorCodes.ResourceTemporarilyUnavailable)
        {
          Debug.Print("-----Server down, log to file instead-----");
          SDLogger.Write(_message);
        }
      }
    }

    /// <summary>
    /// Issues a request for the root document on the specified server.
    /// </summary>
    /// <param name="Proxy"></param>
    /// <param name="URL"></param>
    /// <param name="port"></param>
    /// <returns></returns>
    private static void GetWebPage(String server, Int32 port)
    {
      //const Int32 c_microsecondsPerSecond = 1000000;

      // Create a socket connection to the specified server and port.
      using (Socket serverSocket = ConnectSocket(server, port))
      {
        serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, -2);
        // Send request to the server.
        //String request = MessageHandler.SendMessage(message);
        Byte[] bytesToSend = Helpers.Encode(_message);
        serverSocket.Send(bytesToSend, bytesToSend.Length, 0);

        // Reusable buffer for receiving chunks of the document.
        //Byte[] buffer = new Byte[1024];

        //// Accumulates the received page as it is built from the buffer.
        //String page = String.Empty;

        //// Wait up to 30 seconds for initial data to be available.  Throws 
        //// an exception if the connection is closed with no data sent.
        ////DateTime timeoutAt = DateTime.Now.AddSeconds(30);
        ////while (serverSocket.Available == 0 && DateTime.Now < timeoutAt)
        ////{
        ////  System.Threading.Thread.Sleep(100);
        ////}

        //// Poll for data until 30-second timeout.  Returns true for data and 
        //// connection closed.
        //while (serverSocket.Poll(10 * c_microsecondsPerSecond,
        //    SelectMode.SelectRead))
        //{
        //  // If there are 0 bytes in the buffer, then the connection is 
        //  // closed, or we have timed out.
        //  if (serverSocket.Available == 0)
        //    break;

        //  // Zero all bytes in the re-usable buffer.
        //  Array.Clear(buffer, 0, buffer.Length);

        //  // Read a buffer-sized HTML chunk.
        //  Int32 bytesRead = serverSocket.Receive(buffer);

        //  // Append the chunk to the string.
        //  page = page + Helpers.Decode(buffer);
        //}

        // Return the complete string.
        //Debug.Print("I got: " + page);
        //return "";//page;
      }
    }

    /// <summary>
    /// Creates a socket and uses the socket to connect to the server's IP 
    /// address and port.
    /// </summary>
    /// <param name="server"></param>
    /// <param name="port"></param>
    /// <returns></returns>
    private static Socket ConnectSocket(String server, Int32 port)
    {
      // Get server's IP address.
      IPHostEntry hostEntry = Dns.GetHostEntry(server);

      // Create socket and connect to the server's IP address and port
      Socket socket = new Socket(AddressFamily.InterNetwork,
          SocketType.Stream, ProtocolType.Tcp);
      socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, -2);

      socket.Connect(new IPEndPoint(IPAddress.Parse(server), port));
      return socket;
    }
    public enum SocketErrorCodes
    {
      InterruptedFunctionCall = 10004,
      PermissionDenied = 10013,
      BadAddress = 10014,
      InvalidArgument = 10022,
      TooManyOpenFiles = 10024,
      ResourceTemporarilyUnavailable = 10035,
      OperationNowInProgress = 10036,
      OperationAlreadyInProgress = 10037,
      SocketOperationOnNonSocket = 10038,
      DestinationAddressRequired = 10039,
      MessgeTooLong = 10040,
      WrongProtocolType = 10041,
      BadProtocolOption = 10042,
      ProtocolNotSupported = 10043,
      SocketTypeNotSupported = 10044,
      OperationNotSupported = 10045,
      ProtocolFamilyNotSupported = 10046,
      AddressFamilyNotSupported = 10047,
      AddressInUse = 10048,
      AddressNotAvailable = 10049,
      NetworkIsDown = 10050,
      NetworkIsUnreachable = 10051,
      NetworkReset = 10052,
      ConnectionAborted = 10053,
      ConnectionResetByPeer = 10054,
      NoBufferSpaceAvailable = 10055,
      AlreadyConnected = 10056,
      NotConnected = 10057,
      CannotSendAfterShutdown = 10058,
      ConnectionTimedOut = 10060,
      ConnectionRefused = 10061,
      HostIsDown = 10064,
      HostUnreachable = 10065,
      TooManyProcesses = 10067,
      NetworkSubsystemIsUnavailable = 10091,
      UnsupportedVersion = 10092,
      NotInitialized = 10093,
      ShutdownInProgress = 10101,
      ClassTypeNotFound = 10109,
      HostNotFound = 11001,
      HostNotFoundTryAgain = 11002,
      NonRecoverableError = 11003,
      NoDataOfRequestedType = 11004
    }
  }

}
